Em C++, toda expressão resulta em um lvalue ou um rvalue. Essa distinção define se uma expressão se refere à identidade (onde está) ou seu valor (o que contém).
1. Identidade vs. Conteúdo
Um lvalue (valor de localização) representa um objeto com um endereço de memória persistente. Pense nele como uma caixa rotulada na memória RAM. Por outro lado, um rvalue (valor de leitura) é transitório; representa um resultado temporário ou uma constante literal que não possui um endereço acessível ao programador.
2. Transições Funcionais
Enquanto um lvalue pode atuar como rvalue (o compilador simplesmente recupera o valor dentro da caixa), o inverso é proibido. Você não pode usar um rvalue onde um lvalue é exigido — por exemplo, você não pode obter o endereço de um número literal como &42 porque ele carece de uma identidade persistente.
$$ \text{Lvalue} \xrightarrow{\text{Conversão}} \text{Rvalue} \quad (\text{Permitido}) $$
$$ \text{Rvalue} \xrightarrow{\text{Atribuição}} \text{Lvalue} \quad (\text{Proibido}) $$